// import Cookies from 'js-cookie'
import { local as Cookies } from '@/libs/store'
// cookie保存的天数
import config from '@/config'
import { forEach, hasOneOf, objEqual } from '@/libs/tools'
import i18n from '@/i18n'
import XLSX from 'xlsx'
import FileSaver from 'file-saver'
const { title, cookieExpires, validTime, useI18n, homeName: HOME_NAME } = config

export const TOKEN_KEY = 'token'
export const COOKIE_KEY = 'zrdq'

const frontValid = validTime - 20

export const setCookiesInfo = (info, key = COOKIE_KEY) => {
  info = typeof info === 'object' ? JSON.stringify(info) : info
  // Cookies.set(COOKIE_KEY, info, { 'max-age': frontValid + ';' })
  Cookies.set(key, info, frontValid * 1000)
}

export const updateCookiesMaxAge = (key = COOKIE_KEY) => {
  const cookie = getCookiesInfo(key)
  if (!_.isEmpty(cookie)) {
    const info = JSON.stringify(cookie)
    Cookies.set(key, info, frontValid * 1000)
  }
}

export const getCookiesInfo = (key = COOKIE_KEY) => {
  const info = Cookies.get(key)
  if (info) return JSON.parse(info)
  else return {}
}

export const clearCookiesInfo = () => {
  Cookies.set(COOKIE_KEY, '{}')
}

export const hasChild = item => {
  return item.children && item.children.length !== 0
}

// 运营商默认
const agentMenuDefault = [
  {
    name: 'agent',
    parent: null
  },
  {
    name: 'user_edit',
    parent: 'agent'
  },
  {
    name: 'charge_station',
    parent: 'agent'
  },
  {
    name: 'user_manage',
    parent: null
  },
  {
    name: 'login_user_manage',
    parent: 'user_manage'
  },
  {
    name: 'login_rule_manage',
    parent: 'user_manage'
  },
  {
    name: 'login_log',
    parent: 'user_manage'
  },
  {
    name: 'login_msg',
    parent: 'user_manage'
  }
]

// 充电站默认
const stationMenuDefault = []

const showThisMenuEle = (item, user) => {
  // if (item.meta && item.meta.access && item.meta.access.length) {
  //   if (hasOneOf(item.meta.access, access)) return true
  //   else return false
  // } else return true
  const { menuList } = getCookiesInfo()
  const { name } = item
  const whiteList = [
    { name: 'login' },
    { name: 'root' },
    { name: 'menuManage' },
    { name: 'menu_list' },
    { name: 'error_401' },
    { name: 'error_500' },
    { name: 'error_404' }
  ]

  let menu = []

  if (!menuList || menuList.length === 0) {
    if (user.operatorId != 0) {
      menu = agentMenuDefault.concat(whiteList)
    } else if (user.stationId != 0) {
      menu = stationMenuDefault.concat(whiteList)
    }
  } else {
    menu = menuList.concat(whiteList)
  }

  return menu.find(m => m.name === name)
}
/**
 * @param {Array} list 通过路由列表得到菜单列表
 * @returns {Array}
 */
export const getMenuByRouter = (list, user) => {
  console.log('========= getMenuByRouter ====== ', list, user)
  const res = []
  forEach(list, item => {
    if (!item.meta || (item.meta && !item.meta.hideInMenu)) {
      const obj = {
        icon: (item.meta && item.meta.icon) || '',
        name: item.name,
        meta: item.meta
      }
      if (
        (hasChild(item) || (item.meta && item.meta.showAlways)) &&
        showThisMenuEle(item, user)
      ) {
        obj.children = getMenuByRouter(item.children || [], user)
      }
      if (item.meta && item.meta.href) obj.href = item.meta.href
      if (showThisMenuEle(item, user)) res.push(obj)
    }
  })
  console.log('========= getMenuByRouter result ====== ', res)
  return res
}

// 转化用户数据中的菜单数据
// 从路由中过滤响应的数据
export const transformMenus = (list, menus, isAdmin) => {
  const arr = []
  list.forEach(l => {
    const t = menus.find(m => m.name === l.name)
    if (t) {
      arr.push({
        name: l.name,
        meta: t.meta,
        icon: t.meta && t.meta.icon || t.icon || '',
        pid: l.pid,
        id: l.id
        // title: isAdmin ? i18n.t(l.name) : l.titlename
        // showMenus: t.showMenus || []
      })
    }
  })
  return arr
}

// 把用户的菜单数据转化为菜单数据
export const toAccessTree = (list) => {
  list.forEach(l => {
    const { pid, id } = l
    const p = list.find(s => s.id === pid)
    if (pid !== 0 && p) {
      !p.children && (p.children = [])
      p.children.push(l)
    }
  })
  return list.filter(l => l.pid === 0)
}

// 过滤不显示的子菜单
export const filterTree = (tree) => {
  tree.forEach(t => {
    const { showMenus = [], children = [] } = t
    if (showMenus.length && children.length) {
      t.children = children.filter(c => _.includes(showMenus, c.name))
    }
    if (t.children && t.children.length) {
      filterTree(t.children)
    }
  })
}

// 根据用户返回的菜单数据，反显菜单
export const getMenuByUserAccess = (access = [], allMenus, isAdmin) => {
  const newMenus = transformMenus(access, allMenus, isAdmin)
  const tree = toAccessTree(newMenus)
  // filterTree(tree)
  // if (isAdmin) {
  //   // 添加菜单管理到菜单树中
  //   const menu = allMenus.find(m => m.name === 'menuManage')
  //   menu && tree.unshift({ ...menu })
  // }
  return tree
}

// 根据用户级别过滤菜单信息，不同用户级别对应的总菜单不同
export const filterMenuByUserLevel = (roleMenus = [], allMenus = []) => {
  const res = []
  console.log('---------------------------------- i18n')
  console.log(i18n)
  roleMenus.forEach(t => {
    const d = allMenus.find(d => d.name == t.name)
    if (d) {
      const a = _.assign({}, d, t.title ? { titlename: i18n.t(t.title) } : {})
      res.push(a)
    }
  })
  return res
}

/**
 * @param {Array} routeMetched 当前路由metched
 * @returns {Array}
 */
export const getBreadCrumbList = (route, homeRoute) => {
  const homeItem = { ...homeRoute, icon: homeRoute.meta.icon }
  const routeMetched = route.matched
  if (routeMetched.some(item => item.name === homeRoute.name)) return [homeItem]
  const res = routeMetched
    .filter(item => {
      return item.meta === undefined || !item.meta.hideInBread
    })
    .map(item => {
      const meta = { ...item.meta }
      if (meta.title && typeof meta.title === 'function') {
        meta.__titleIsFunction__ = true
        meta.title = meta.title(route)
      }
      const obj = {
        icon: (item.meta && item.meta.icon) || '',
        name: item.name,
        meta: meta
      }
      return obj
    })
  // res = res.filter(item => {
  //   return !item.meta.hideInMenu
  // })
  return [{ ...homeItem, to: homeRoute.path }, ...res]
}

export const getRouteTitleHandled = route => {
  const router = { ...route }
  const meta = { ...route.meta }
  let title = ''
  if (meta.title) {
    if (typeof meta.title === 'function') {
      meta.__titleIsFunction__ = true
      title = meta.title(router)
    } else title = meta.title
  }
  meta.title = title
  router.meta = meta
  return router
}

export const showTitle = (item, vm) => {
  let { title, __titleIsFunction__, useTitle } = item.meta
  if (item.title) return item.title
  if (useTitle) return vm.$t(useTitle)
  if (useI18n) {
    if (title.includes('{{') && title.includes('}}') && useI18n) {
      title = title.replace(/({{[\s\S]+?}})/, (m, str) =>
        str.replace(/{{([\s\S]*)}}/, (m, _) => vm.$t(_.trim()))
      )
    } else if (__titleIsFunction__) title = item.meta.title
    else title = vm.$t(item.name)
  } else title = (item.meta && item.meta.title) || item.name
  return title
}

/**
 * @description 本地存储和获取标签导航列表
 */
export const setTagNavListInLocalstorage = list => {
  localStorage.tagNaveList = JSON.stringify(list)
}
export const setFrontTagNavListInLocalstorage = list => {
  localStorage.frontTagNaveList = JSON.stringify(list)
}

/**
 * @returns {Array} 其中的每个元素只包含路由原信息中的name, path, meta三项
 */
export const getTagNavListFromLocalstorage = () => {
  const list = localStorage.tagNaveList
  return list ? JSON.parse(list) : []
}

export const getFrontTagNavListFromLocalstorage = () => {
  const list = localStorage.frontTagNaveList
  return list ? JSON.parse(list) : []
}

/**
 * @param {Array} routers 路由列表数组
 * @description 用于找到路由列表中name为home的对象
 */
export const getHomeRoute = (routers, homeName = HOME_NAME) => {
  let i = -1
  const len = routers.length
  let homeRoute = {}
  while (++i < len) {
    const item = routers[i]
    if (item.children && item.children.length) {
      const res = getHomeRoute(item.children, homeName)
      if (res.name) {
        return res
      }
    } else {
      if (item.name === homeName) {
        homeRoute = item
      }
    }
  }
  return homeRoute
}

/**
 * @param {*} list 现有标签导航列表
 * @param {*} newRoute 新添加的路由原信息对象
 * @description 如果该newRoute已经存在则不再添加
 */
export const getNewTagList = (list, newRoute) => {
  const { name, path, meta, params, query } = newRoute
  const newList = [...list]
  const index = newList.findIndex(item => routeEqual(item, newRoute))
  if (index > -1) {
    newList.splice(index, 1, { name, path, meta, params, query })
    return newList
  }
  newList.push({ name, path, meta, params, query })
  return newList
}

/**
 * @param {*} access 用户权限数组，如 ['super_admin', 'admin']
 * @param {*} route 路由列表
 */
const hasAccess = (access, route) => {
  if (route.meta && route.meta.access) {
    return hasOneOf(access, route.meta.access)
  } else return true
}

/**
 * 权鉴
 * @param {*} to 即将跳转的路由
 * @param {*} access 用户权限数组
 * @param {*} routes 路由列表
 * @description 用户是否可跳转到该页
 */
export const canTurnTo = (to, access, routes) => {
  const routePermissionJudge = list => {
    return list.some(item => {
      if (item.children && item.children.length) {
        return routePermissionJudge(item.children)
      } else if (item.name === to.name || to.path === '/') {
        // return hasAccess(access, item)
        return true
      }
    })
  }

  return routePermissionJudge(routes)
}

/**
 * @param {String} url
 * @description 从URL中解析参数
 */
export const getParams = url => {
  const keyValueArr = url.split('?')[1].split('&')
  const paramObj = {}
  keyValueArr.forEach(item => {
    const keyValue = item.split('=')
    paramObj[keyValue[0]] = keyValue[1]
  })
  return paramObj
}

/**
 * @param {Array} list 标签列表
 * @param {String} name 当前关闭的标签的name
 */
export const getNextRoute = (list, route) => {
  let res = {}
  const index = list.findIndex(item => routeEqual(item, route))
  if (index === list.length - 1) res = list[list.length - 2]
  else res = list[index + 1]
  return res
}

/**
 * @param {Number} times 回调函数需要执行的次数
 * @param {Function} callback 回调函数
 */
export const doCustomTimes = (times, callback) => {
  let i = -1
  while (++i < times) {
    callback(i)
  }
}

/**
 * @param {Object} file 从上传组件得到的文件对象
 * @returns {Promise} resolve参数是解析后的二维数组
 * @description 从Csv文件中解析出表格，解析成二维数组
 */
export const getArrayFromFile = file => {
  const nameSplit = file.name.split('.')
  const format = nameSplit[nameSplit.length - 1]
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsText(file) // 以文本格式读取
    let arr = []
    reader.onload = function (evt) {
      const data = evt.target.result // 读到的数据
      const pasteData = data.trim()
      arr = pasteData
        .split(/[\n\u0085\u2028\u2029]|\r\n?/g)
        .map(row => {
          return row.split('\t')
        })
        .map(item => {
          return item[0].split(',')
        })
      if (format === 'csv') resolve(arr)
      else reject(new Error('[Format Error]:你上传的不是Csv文件'))
    }
  })
}

/**
 * @param {Array} array 表格数据二维数组
 * @returns {Object} { columns, tableData }
 * @description 从二维数组中获取表头和表格数据，将第一行作为表头，用于在iView的表格中展示数据
 */
export const getTableDataFromArray = array => {
  let columns = []
  let tableData = []
  if (array.length > 1) {
    const titles = array.shift()
    columns = titles.map(item => {
      return {
        title: item,
        key: item
      }
    })
    tableData = array.map(item => {
      const res = {}
      item.forEach((col, i) => {
        res[titles[i]] = col
      })
      return res
    })
  }
  return {
    columns,
    tableData
  }
}

export const findNodeUpper = (ele, tag) => {
  if (ele.parentNode) {
    if (ele.parentNode.tagName === tag.toUpperCase()) {
      return ele.parentNode
    } else {
      return findNodeUpper(ele.parentNode, tag)
    }
  }
}

export const findNodeUpperByClasses = (ele, classes) => {
  const parentNode = ele.parentNode
  if (parentNode) {
    const classList = parentNode.classList
    if (
      classList &&
      classes.every(className => classList.contains(className))
    ) {
      return parentNode
    } else {
      return findNodeUpperByClasses(parentNode, classes)
    }
  }
}

export const findNodeDownward = (ele, tag) => {
  const tagName = tag.toUpperCase()
  if (ele.childNodes.length) {
    let i = -1
    const len = ele.childNodes.length
    while (++i < len) {
      const child = ele.childNodes[i]
      if (child.tagName === tagName) return child
      else return findNodeDownward(child, tag)
    }
  }
}

export const showByAccess = (access, canViewAccess) => {
  return hasOneOf(canViewAccess, access)
}

/**
 * @description 根据name/params/query判断两个路由对象是否相等
 * @param {*} route1 路由对象
 * @param {*} route2 路由对象
 */
export const routeEqual = (route1, route2) => {
  const params1 = route1.params || {}
  const params2 = route2.params || {}
  const query1 = route1.query || {}
  const query2 = route2.query || {}
  return (
    route1.name === route2.name &&
    objEqual(params1, params2) &&
    objEqual(query1, query2)
  )
}

/**
 * 判断打开的标签列表里是否已存在这个新添加的路由对象
 */
export const routeHasExist = (tagNavList, routeItem) => {
  const len = tagNavList.length
  let res = false
  doCustomTimes(len, index => {
    if (routeEqual(tagNavList[index], routeItem)) res = true
  })
  return res
}

export const localSave = (key, value) => {
  localStorage.setItem(key, value)
}

export const localRead = key => {
  return localStorage.getItem(key) || ''
}

// scrollTop animation
export const scrollTop = (el, from = 0, to, duration = 500, endCallback) => {
  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame =
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function (callback) {
        return window.setTimeout(callback, 1000 / 60)
      }
  }
  const difference = Math.abs(from - to)
  const step = Math.ceil((difference / duration) * 50)

  const scroll = (start, end, step) => {
    if (start === end) {
      endCallback && endCallback()
      return
    }

    let d = start + step > end ? end : start + step
    if (start > end) {
      d = start - step < end ? end : start - step
    }

    if (el === window) {
      window.scrollTo(d, d)
    } else {
      el.scrollTop = d
    }
    window.requestAnimationFrame(() => scroll(d, end, step))
  }
  scroll(from, to, step)
}

/**
 * @description 根据当前跳转的路由设置显示在浏览器标签的title
 * @param {Object} routeItem 路由对象
 * @param {Object} vm Vue实例
 */
export const setTitle = (routeItem, vm) => {
  const handledRoute = getRouteTitleHandled(routeItem)
  const pageTitle = showTitle(handledRoute, vm)
  const resTitle = pageTitle ? `${title} - ${pageTitle}` : title
  window.document.title = resTitle
}

export const expandTree = (tree, res) => {
  tree.forEach(t => {
    res.push(t)
    if (t.children && t.children.length) {
      expandTree(t.children, res)
    }
  })
}

export const findItemInTree = (name, tree) => {
  // tree.forEach(t => {
  //   if (t.name == name) {
  //     return t
  //   } else if (t.children) {
  //     return findItemInTree(name, t.children)
  //   }
  // })
  for (let i = 0; i < tree.length; i++) {
    const t = tree[i]
    if (t.name == name) {
      return t
    } else if (t.children) {
      return findItemInTree(name, t.children)
    }
  }
}

export const asyncDownloadExcel = ({ $el, filename = 'sheet' }) => {
  // 详细参数参见 https://www.npmjs.com/package/xlsx
  const wb = XLSX.utils.table_to_book($el, { raw: true })
  const wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
  try {
    FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), `${filename}.xlsx`)
  } catch (e) {
    console.error(e)
  }
}
